import store from '@/store'
import crypto from '@/utils/crypto'
import { getUuid } from '@/utils/utils'
//
// 域名 URL前缀 和服务的管理
let baseUrl = {};
let envPrefix = ""
// 后端
export let domain = 'https://hiep-test.fintechabchina.com/NJZLFinancingApply/shkp/travelBack'
//https://hiep-test.fintechabchina.com/jtp-dev/jtp-proxy/

baseUrl = {
	// user: domain + envPrefix + 'user',
	// TODO 是否加密 测试环境加密/jkbpuser 不加密/jkbp/user
	// user: store.state.isCrypto ? domain + envPrefix + '/NJZLFinancingApply/shkp/staffBack' : domain + envPrefix + '/NJZLFinancingApply/shkp/staffBack'
	user: store.state.isCrypto ? domain + envPrefix + '/shkp/staff' : domain + envPrefix + '/shkp/staff',
	jtp: store.state.isCrypto ? domain + envPrefix + '/jtpdev/jtp-proxy' : domain + envPrefix + ''
}

const commonParameter = {
	"appChannelCode": "SHKP",
	"appCityCode": "string",
	"appId": "SHKP",
	"appIpAddress": "string",
	"appMacAddress": "string",
	"channelCode": "SHKP002",
	"cityCode": "string",
	data:{},
	"encryptData": "string",
	"encryptType": "SM4",
	"extension": {
		"encrypt-secret-key": "string",
		"encrypt-salt": "string",
		"uuid":"string"
	},
	"extensionObject": {
		// "ssIToken":"qwert",
		"ssIToken":"",
		"langCode":"zh_CN"
	},
	"flowNum": 0,
	"msgType": "string",
	"nonceString": "string",
	"requestId": "string",
	"signStamp": "string",
	"signType": "string",
	"specVersion": "string",
	"terminalId": "string",
	"timestamp": new Date().valueOf() + Number(uni.getStorageSync('timeDiff') || ''),
	"trCode": "string",
	"trToken": "",
	// 'trToken':'mkhh_IAAAABfmn9oZiel0YjZNQMUV64EWakNcSbg9fHhe04U3WTmOYQEAAAHlZf_s5r492rsEU1Xw4JP3wfZwWxls9Hl6Vu6rudKsPMEHdQ9e-acM8QgwZdIyb75eTjmD4NXyx6KPZcXlsoeKU3nICM-SI0ZKxShEngit4nBTBhFBNlH8GxLPkByoCsLV86gLFwlvq2_Z2dbNaBQ0USn0Yd0tALza-XTfeznC78eHMlSVD7fRr1xJ_cf0Tyi-gTzXA2wy4Fj4nKBvSn4wWyE4blPby9itbfw_WJKhTasYAy6vjjMbiv4871DTagaZecfB5WJ3mNuMSdMVHlxXfQU6RsbKkb5ErSphT1zr6tlpxsaWCY0_NJ2BrEB5x6-QpEADXcXh4Mwhh_z_p77mwO92UZVviCPb5tkpNsncwBmmc2KGiGTlxfmp0al_AAkYCRvni3fecg6jroV2yWJHp3x6iaxWH0spaCZkANiBKw71asGHzP2IIRLjjVMYsqtuCHpLsxIVzA6HWqsbu8K6',
	"trVersion": "1.0.0",
	"uniqueId": "116185C862A5BFAD",
	"userId": "",
	"initRespError":""
}

// AES加密
const cryptoParameter = (data) => {
	// console.log("data", data)
	let RSAPk = uni.getStorageSync('rsaPk')
	let param = JSON.parse(JSON.stringify(commonParameter))
	let AESKey = crypto.randomNumber(32)
	let salt = crypto.randomNumber()
	let iv = crypto.randomNumber()
	// console.log("AESKey", AESKey,"salt", salt,"iv", iv,"RSAPk", uni.getStorageSync('rsaPk'))
	param.encryptType = 'AES'
	param.signType = 'SHA256'

	param.extension["encrypt-salt"] = crypto.encryptRSA(salt, RSAPk)
	param.extension["encrypt-secret-key"] = crypto.encryptRSA(AESKey + "|" + iv, RSAPk)

	param.extension["uuid"] = getUuid()
	store.dispatch('add_uuid', { id: param.extension["uuid"], key: AESKey, iv: iv, salt: salt })

	param.data = data
	param.nonceString = ''
	param.nonceString = crypto.encryptAES(crypto.encryptSHA256Encode(param.timestamp + salt + JSON.stringify(crypto.sortParam(param))), AESKey, iv)
	param.data = crypto.encryptAES(JSON.stringify(data), AESKey, iv)
	return param
}

// AES解密
const decryptResonse = (response) => {
	let param = response
	const { key, iv, salt } = store.getters['getKey'](param.extension['uuid'])
	let data = crypto.decryptAES(param.data, key, iv)
	store.dispatch('del_uuid', param.extension['uuid'])
	param.data = JSON.parse(data)

	let nonceString = param.nonceString
	param.nonceString = ''
	let sign = crypto.encryptSHA256Encode(param.timestamp + salt + JSON.stringify(crypto.sortParam(param)))
	if (sign != crypto.decryptAES(nonceString, key, iv)) {
		console.log('验签失败')
		return;
	}
	return param
}


function awaitWrapper(promise) {
	return promise.then(data => [null, data]).catch(err => [err, null]);
}
function errorMessage(statusCode) {
	console.log('statusCode: ', statusCode);
	switch (statusCode) {
		case 400:
			uni.showToast({
				title: '系统状态异常，请联系管理员解决。',
				icon: 'none',
				duration: 2500
			})
			break
		case 401:
			uni.showToast({
				title: '访问出错了，请联系管理员处理。',
				icon: 'none',
				duration: 2500
			})
			break
		case 403:
			uni.showToast({
				title: '当前访问的资源受限，请稍后重试。',
				icon: 'none',
				duration: 2500
			})
			break
		case 404:
			uni.showToast({
				title: '抱歉，无法找到您想要的资源，请联系管理员。',
				icon: 'none',
				duration: 2500
			})
			break
		case 405:
			uni.showToast({
				title: '访问出错了，请联系管理员处理。',
				icon: 'none',
				duration: 2500
			})
			break
		case 406:
			uni.showToast({
				title: '访问出错了，请联系管理员解决。',
				icon: 'none',
				duration: 2500
			})
			break
		case 408:
			uni.showToast({
				title: '您当前的网络不佳，请稍后重试。',
				icon: 'none',
				duration: 2500
			})
			break
		case 409:
			uni.showToast({
				title: '访问出错，请联系管理员解决。',
				icon: 'none',
				duration: 2500
			})
			break
		case 410:
			uni.showToast({
				title: '所请求的资源已不存在，请确认。',
				icon: 'none',
				duration: 2500
			})
			break
		case 417:
			uni.showToast({
				title: '访问出错，请联系管理员解决。',
				icon: 'none',
				duration: 2500
			})
			break
		case 429:
			uni.showToast({
				title: '系统忙不过来了，请稍后重试。',
				icon: 'none',
				duration: 2500
			})
			break
		case 500:
			uni.showToast({
				title: '系统状态异常，请联系管理员解决。',
				icon: 'none',
				duration: 2500
			})
			break
		case 501:
			uni.showToast({
				title: '网络异常，请稍后重试。',
				icon: 'none',
				duration: 2500
			})
			break
		case 502:
			uni.showToast({
				title: '网络错误，请稍后重试。',
				icon: 'none',
				duration: 2500
			})
			break
		case 503:
			uni.showToast({
				title: '系统维护，请稍后重试。',
				icon: 'none',
				duration: 2500
			})
			break
		case 504:
			uni.showToast({
				title: '服务器异常，请联系管理员处理。',
				icon: 'none',
				duration: 2500
			})
			break
		case 505:
			uni.showToast({
				title: '系统状态异常，请联系管理员解决。',
				icon: 'none',
				duration: 2500
			})
			break
		default:
			uni.showToast({
				title: '这种异常被您遇到了，请联系管理员吧。',
				icon: 'none',
				duration: 2500
			})
			break
	}
}

const request = (config) => {
	// console.log('config:',config);
	let token = uni.getStorageSync('token') || "zhangye"
	// let token = "chailvzhuanyong"
	let defaultConfig = {
		method: "POST",
		showLoading: config.showLoading,
		header: {
			'content-type': 'application/json',
			'Authentication': '715fa4d8c12a3033f69c25de9150b61b7880ce502eb4b4dac950f8bdc3b6a777',
			'token': token,
			// 'Authentication':'mkhh_IAAAABfmn9oZiel0YjZNQMUV64EWakNcSbg9fHhe04U3WTmOYQEAAAHlZf_s5r492rsEU1Xw4JP3wfZwWxls9Hl6Vu6rudKsPMEHdQ9e-acM8QgwZdIyb75eTjmD4NXyx6KPZcXlsoeKU3nICM-SI0ZKxShEngit4nBTBhFBNlH8GxLPkByoCsLV86gLFwlvq2_Z2dbNaBQ0USn0Yd0tALza-XTfeznC78eHMlSVD7fRr1xJ_cf0Tyi-gTzXA2wy4Fj4nKBvSn4wWyE4blPby9itbfw_WJKhTasYAy6vjjMbiv4871DTagaZecfB5WJ3mNuMSdMVHlxXfQU6RsbKkb5ErSphT1zr6tlpxsaWCY0_NJ2BrEB5x6-QpEADXcXh4Mwhh_z_p77mwO92UZVviCPb5tkpNsncwBmmc2KGiGTlxfmp0al_AAkYCRvni3fecg6jroV2yWJHp3x6iaxWH0spaCZkANiBKw71asGHzP2IIRLjjVMYsqtuCHpLsxIVzA6HWqsbu8K5',
			'x-app-id': 'jkbp-user',
		}
	}
	config = {
		...defaultConfig,

		...config
	}

	// 是否trcode请求
	if (!config.url || config.url == '/') {
		config.header['X-User-Code-Enable'] = 'true'
		// 另一种方法 初始化获取字典交易码，通过接口标志位获取对应交易码，交易码改变不影响标志位
		if (config.trCode) {
			commonParameter.trCode = config.trCode
		} else {
		}
	} else {
		config.header['X-User-Code-Enable'] = 'false'
		commonParameter.trCode = ''
	}

	if (token) {
		commonParameter.trToken = token
		let userId = uni.getStorageSync('userId')
		commonParameter.userId = userId
	} else {
		commonParameter.trToken = ''
		commonParameter.userId = ''
	}
	
	// 请求报文
	// 是否加密
	if (store.state.isCrypto) {
		if (!uni.getStorageSync('uniqueId')) {
			let uuid = getUuid()
			uni.setStorageSync('uniqueId', uuid)
		}
		commonParameter.uniqueId = uni.getStorageSync('uniqueId')
		if (config.url.includes('generatePublicKey') || config.trCode == 'STAFF0046') {
			commonParameter.encryptType = 'AES'
			commonParameter.data = config.data
			config.data = { data: config.data, ...commonParameter }
		} else {
			config.data = cryptoParameter(config.data)
		}
	} else {
		commonParameter.data = config.data
		config.data = { data: config.data, ...commonParameter }
	}

	// 处理 url
	if (!(config.url.startsWith('http://') || config.url.startsWith('https://'))) {
		// config.url = domain;
		config.url = baseUrl[config.module] + config.url;
	}

	let promise = new Promise(function (resolve, reject) {
		if (config.showLoading) {
			uni.showLoading({
				title: '处理中...'
			});
		}

		// 没有token获取用户信息跳转登录
		if ((config.url.includes('getUserInfo') || config.data.trCode == 'TO000223') && !config.header.token) {
			uni.redirectTo({
				url: '/pages/index/authorize'
			})
			uni.hideLoading();
			return;
		}

		uni.request(config).then(async responses => {
			uni.hideLoading();
			if (responses[0]) {
				console.log('报错～～～');
				// 此处提示网络超时或？
				errorMessage(responses[0].statusCode);
				// 抛出异常信息
				reject({
					...responses[0]
				});
			} else {
				let response;
				// 是否加密
				if (store.state.isCrypto) {
					// TODO返回报文是否加密根据以下路径或者trCode判断，包含则不加密，反之则加密，如有调整还需修改
					// 如果使用trcode 该接口返回数据不加密的话 需要手动在这里里添加
					let isDecrypt = false;
					if (responses[1].data.trCode) {
						// 返回数据不加密的trcode
						let decryptResTrcode = ['STAFF0046']
						decryptResTrcode.findIndex((item) => {
							if (item == responses[1].data.trCode) {
								isDecrypt = true
							}
						})
					} else {
						// 返回数据不加密URL包含的字符串
						let decryptoResUrl = ['singleMenuCheck', 'getUserInfo', '/generateSecret/generatePublicKey', '/app/item/allItemSearch', '/app/item/querySquarAndBottomMenu', '/app/item/queryBanner', '/ufile/download', '/user/menu/list', '/menu/allTree', '/trade/list']
						decryptoResUrl.findIndex((item) => {
							if (config.url.includes(item)) {
								isDecrypt = true
							}
						})
						if (config.trCode == 'STAFF0046') {
							isDecrypt = true
						}
					}
					if (isDecrypt) {
						response = responses[1].data;
					} else {
						response = decryptResonse(responses[1].data)
					}
				} else {
					response = responses[1].data;
				}
				if (response.resCode != 200 && response.resCode != 0) {
					// errorMessage(response.resCode);
					uni.showToast({
						title: response.errorDescription || response.resMessage,
						icon: 'none',
						duration: 2500
					})
					// reject({
					// 	...response
					// })
					resolve(response.data);
					return;
				};
				if (response.data.respCode === "FJKBP0000") { //data.data
					resolve(response.data);
					
				} else if (response.data.respCode === "FJKBP0048") {
					// token过期统一处理
					uni.showModal({
						title: '提示',
						content: '用户信息已过期，是否重新授权？',
						success: function (res) {
							uni.removeStorageSync("token");
							uni.removeStorageSync("userId");
							uni.removeStorageSync("isAuth");
							uni.removeStorageSync("rsaPk");
							uni.removeStorageSync("uniqueId");
							uni.removeStorageSync("tabBarList");
							if (res.confirm) {
								uni.redirectTo({
									url: '/pages/index/authorize'
								})
							} else if (res.cancel) {
								uni.reLaunch({
									url: '/pages/index/index'
								})
							}
						}
					});
					reject({
						...response
					})
					return;
				} else if (response.data.respCode == 'FJKBP9999') {
					uni.showToast({
						title: response.data.respMsg,
						icon: 'none',
						duration: 2500
					})
					reject({
						...response
					})
				} else {
					uni.showToast({
						title: response.data.respMsg,
						icon: 'none',
						duration: 2500
					})
					// 抛出信息 因接口返回成功暂不做提示处理
					reject({
						...response
					});
				}
			}
		}).catch(error => {
			console.log('request——catch');
			uni.hideLoading()
			// 此处提示网络超时或?
			uni.showToast({
				title: '网络超时',
				icon: 'none',
				duration: 3000
			})
			// 抛出异常
			reject(error);
		}).finally((result) => {
			uni.hideLoading()
		});
	})
	return awaitWrapper(promise)
};

export default request;
